package com.code9xs.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.code9xs.mapper.*;
import com.code9xs.pojo.*;
import com.code9xs.service.AssociationService;
import com.code9xs.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author Suhd
 * @date 2021/4/25
 * @time 14:24
 * @wechat i9xswanan
 * @github https://github.com/Code9xs
 */
@Transactional
@Service
public class AssociationServiceImpl implements AssociationService {
    @Autowired
    private AssociationMapper associationMapper;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private TitleMapper titleMapper;

    @Autowired
    private AssociationDepartmentMapper departmentMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserAssociationMapper userAssociationMapper;

    @Autowired
    private AssociationInformationMapper associationInformationMapper;

    @Autowired
    private AssociationDepartmentMapper associationDepartmentMapper;

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private AnnouncementMapper  announcementMapper;

    @Autowired
    private UserActivityMapper userActivityMapper;

    @Autowired
    private ToDoMapper toDoMapper;

    @Autowired
    private CommonUtils commonUtils;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public boolean createAssociation(JSONObject param) {

        Integer isExist = associationMapper.selectIsExistByName(param.getString("name"));
        if (isExist > 0){
            return false;
        }
        final UserAssociation userAssociation = new UserAssociation();
        final UserRole userRole = new UserRole();
        Integer aid = IDPoolUtil.getAID();
        User currentUser = userService.getCurrentUser();
        userRole.setAssociation(aid);
        userRole.setRid(4);
        userRole.setUid(currentUser.getId());
        userRoleMapper.insertSelective(userRole);
        Association association = new Association(
                aid,
                param.getString("name"),
                currentUser.getId(),
                param.getString("profile"),
                DateUtils.getCurrentTime(),
                param.getString("type"),
                "申请已提交",
                param.getString("associationAvatar"));
        // 处理职称
        JSONArray titles = param.getJSONArray("title");
        userAssociation.setUid(currentUser.getId());
        userAssociation.setAid(aid);
        userAssociationMapper.insertSelective(userAssociation);
        List<Title> titleList = new ArrayList<>();
        for (int i = 0;i < titles.size(); i++){
            String titlesString = titles.getString(i);
            Title title = new Title();
            title.setTitle(titlesString);
            title.setAid(aid);
            title.setStatus("申请已提交");
            titleList.add(title);
        }
        // 处理部门
        JSONArray dept = param.getJSONArray("department");

        List<AssociationDepartment> departmentList = new ArrayList<>();
        for (int i = 0;i< dept.size();i++){
            String deptString = dept.getString(i);
            AssociationDepartment department = new AssociationDepartment();
            department.setAid(aid);
            department.setName(deptString);
            department.setStatus("申请已提交");
            departmentList.add(department);
        }
        associationMapper.insertSelective(association);
        titleMapper.insertBatch(titleList);
        departmentMapper.insertBatch(departmentList);
        commonUtils.addToDo(currentUser.getId(),aid,"申请已提交","创建社团申请");
        return true;
    }

    @Override
    public List<User> getAllMembers(Integer aid) {
        return userMapper.selectAssociationMembersByAid(aid);
    }

    @Override
    public boolean modifyMemberInfo(JSONObject param) {
        Integer uid = param.getInteger("uid");
        Integer aid = param.getInteger("aid");
        Integer titleId = param.getInteger("title_id");
        Integer departmentId = param.getInteger("department_id");
        int flag = userAssociationMapper.updateMemberInfo(uid, aid, titleId, departmentId);
        if (flag > 0){
            return true;
        }
        return false;
    }

    @Override
    public Map<String,Object> getAssociationInfo(Integer aid) {
        Association association = associationMapper.selectByPrimaryKey(aid);
        Map<String,Object> map = new HashMap<>();
        map.put("id",association.getId());
        map.put("time",DateUtils.format(association.getTime(),DateUtils.DATE_TIME_PATTERN));
        map.put("name",association.getName());
        map.put("profile",association.getProfile());
        map.put("members",association.getMembers());
        map.put("master",userMapper.selectByPrimaryKey(association.getMaster()).getUsername());
        map.put("type",association.getType());
        map.put("associationAvatar",association.getAssociationAvatar());
        return map;
    }

    @Override
    public boolean modifyAssociationInfo(JSONObject param) {
        User user = userMapper.selectUserByUsername(param.getString("master"));
        AssociationInformation information = new AssociationInformation();
        information.setAid(param.getInteger("id"));
        information.setStatus("修改信息申请已提交");
        information.setName(param.getString("name"));
        information.setId(IDPoolUtil.getOtherID());
        information.setMaster(user.getId());
        information.setType(param.getString("type"));
        information.setProfile(param.getString("profile"));
        // 处理职称
        JSONArray titles = param.getJSONArray("title");
        List<Title> titleList = new ArrayList<>();
        for (int i = 0;i < titles.size(); i++){
            JSONObject o = titles.getJSONObject(i);
            Title title = new Title();
            title.setAid(param.getInteger("id"));
            title.setTitle(o.getString("title"));
            title.setStatus("修改信息申请已提交");
            titleList.add(title);
        }
        // 处理部门
        JSONArray dept = param.getJSONArray("department");
        List<AssociationDepartment> departmentList = new ArrayList<>();
        for (int i = 0;i< dept.size();i++){
            JSONObject o = dept.getJSONObject(i);
            AssociationDepartment department = new AssociationDepartment();
            department.setName(o.getString("name"));
            department.setAid(param.getInteger("id"));
            department.setStatus("修改信息申请已提交");
            departmentList.add(department);
        }

        associationInformationMapper.insertSelective(information);
        titleMapper.insertBatch(titleList);
        departmentMapper.insertBatch(departmentList);
        return true;
    }

    @Override
    public List<Title> getAssociationTitle(Integer aid) {
        return titleMapper.selectTitleByAid(aid);
    }

    @Override
    public List<AssociationDepartment> getAssociationDepartment(Integer aid) {
        return associationDepartmentMapper.selectDepartmentByAid(aid);
    }

    @Override
    public List<Activity> getAssociationActivityTenImg() {
        return activityMapper.selectFiveImgByTime();
    }

    @Override
    public PageUtil getAllAssociation(JSONObject param) {
        PageUtil pageUtil = new PageUtil();
        Integer pageSize = param.getInteger("pageSize");
        Integer start = param.getInteger("pageNumber") * pageSize;
        pageUtil.setPageSize(pageSize);
        pageUtil.setTotal(associationMapper.selectStatusIsOkAllCount());
        List<Map<String, Object>> maps = associationMapper.selectAllAssociation(start,pageSize);
        maps.forEach(k ->{
            String time = DateUtils.format((Date) k.get("time"), DateUtils.DATE_PATTERN);
            k.put("time",time);
        });
        pageUtil.setData(maps);
        return pageUtil;
    }

    @Override
    public List<Map<String, Object>> getUserAssociationInfo() {
        User currentUser = userService.getCurrentUser();
        List<Map<String, Object>> info = associationMapper.selectUserAssociation(currentUser.getId());
        return info;
    }

    @Override
    public List<Map<String,Object>> getItemInfo(Integer aid) {
        associationMapper.selectItemInfo(aid);
        return associationMapper.selectItemInfo(aid);
    }

    @Override
    public List<String> getItemBanner(Integer aid) {
        return associationMapper.getItemBanner(aid);
    }

    @Override
    public Association getAssociation(Integer id) {
        return associationMapper.selectByPrimaryKey(id);
    }

    @Override
    public PageUtil getAssociationActivity(Integer aid,Integer page,Integer size) {
        PageUtil pageUtil = new PageUtil();
        pageUtil.setPageSize(size);
        pageUtil.setTotal(activityMapper.selectAllCountByAid(aid));
        pageUtil.setPage(page);
        List<Activity> data = activityMapper.selectAssociationActivityPagination(aid, pageUtil.getStartTotal() - 1, size);
        List<Map<String,Object>> list = new ArrayList<>();
        data.forEach(v ->{
            Map<String,Object> map = new HashMap<>();
            String time = DateUtils.format(v.getTime(),DateUtils.DATE_TIME_PATTERN);
            map.put("id",v.getId());
            map.put("aid",v.getAid());
            map.put("name",v.getName());
            map.put("location",v.getLocation());
            map.put("time",time);
            map.put("url", v.getUrl());
            map.put("status",v.getStatus());
            map.put("count", v.getCount());
            map.put("content",v.getContent());
            list.add(map);
        });
        pageUtil.setData(list);
        return pageUtil;
    }

    @Override
    public List<Announcement> getAssociationAnnounce(Integer aid) {
        return announcementMapper.selectAssociationAnnounceByAid(aid);
    }

    @Override
    public Result joinActivity(Integer uid, Integer aid, Integer activityId) {
        int joinedCount = userActivityMapper.selectCountByActivityId(activityId);
        int defaultCount = activityMapper.selectByPrimaryKey(activityId).getCount();
        int userIsJoined = userActivityMapper.selectJoinedUserByUidAndActivityId(uid, activityId);
        if (joinedCount >= defaultCount){
            return Result.fail(HttpServletResponse.SC_FORBIDDEN,"容量已满",null);
        }
        if (userIsJoined > 0){
            return Result.succ(HttpServletResponse.SC_FORBIDDEN,"你已参加该活动，请勿重复参加",null);
        }
        UserActivity userActivity = new UserActivity();
        userActivity.setAid(aid);
        userActivity.setUid(uid);
        userActivity.setActivityId(activityId);
        userActivityMapper.insertSelective(userActivity);
        return Result.succ(HttpServletResponse.SC_OK,"参加成功",null);
    }

    @Override
    public boolean createActivity(Activity activity) {
        int i = activityMapper.insertSelective(activity);
        if (i > 0){
            return true;
        }
        return false;
    }

    @Override
    public boolean createAnnouncement(Announcement announcement) {
        int flag = announcementMapper.insertSelective(announcement);
        if (flag > 0){
            return true;
        }
        return false;
    }

    @Override
    public Result getUserActivityByPagination(Integer currentPage, Integer pageSize) {
        PageUtil pageUtil = new PageUtil();
        Integer uid = userService.getCurrentUser().getId();
        int count = userActivityMapper.selectUserActivityCountByUid(uid);
        pageUtil.setPage(currentPage);
        pageUtil.setTotal(count);
        pageUtil.setPageSize(pageSize);
        List<Map<String, Object>> activities = userActivityMapper.selectUserActivityByPagination(uid, pageUtil.getStartTotal()-1, pageSize);
        activities.forEach(v -> {
            Date time = (Date)v.get("time");
            final String formatTime = DateUtils.format(time, DateUtils.DATE_TIME_PATTERN);
            v.put("time",formatTime);
        });
        pageUtil.setData(activities);
        return Result.succ(HttpServletResponse.SC_OK,"成功",pageUtil);
    }

    @Override
    public PageUtil getAssociationPeopleByPagination(Integer aid, Integer page, Integer pageSize) {
        PageUtil pageUtil = new PageUtil();
        int total = userActivityMapper.selectCountByAid(aid);
        pageUtil.setTotal(total);
        pageUtil.setPage(page);
        pageUtil.setPageSize(pageSize);
        List<Map<String,Object>> userList = userMapper.selectAssociationPeoplePaginationByAid(aid, pageUtil.getStartTotal() - 1, pageSize);
        pageUtil.setData(userList);
        return pageUtil;
    }

    @Override
    public boolean modifyPeopleInformation(Integer uid,Integer aid,Integer tid,Integer did) {
        int flag = userAssociationMapper.updateMemberInfo(uid, aid, tid, did);
        final UserRole userRole = new UserRole();
        userRole.setAssociation(aid);
        userRole.setRid(5);
        userRole.setUid(uid);
        userRoleMapper.insertSelective(userRole);
        if (flag > 0){
            return true;
        }
        return false;
    }

    @Override
    public boolean modifyActivity(Activity activity) {
        int flag = activityMapper.updateByPrimaryKeySelective(activity);
        if (flag > 0){
            return true;
        }
        return false;
    }

    @Override
    public PageUtil getAssociationAnnouncePaginationByAid(Integer aid, Integer page, Integer pageSize) {
        PageUtil pageUtil = new PageUtil();
        final int total = announcementMapper.selectCountByAid(aid);
        pageUtil.setTotal(total);
        pageUtil.setPage(page);
        pageUtil.setPageSize(pageSize);
        List<Map<String, Object>> mapList = announcementMapper.selectAssociationAnnouncementPaginationByAid(aid, pageUtil.getStartTotal() - 1, pageSize);
        mapList.forEach((v) -> {
            v.put("publisher",userMapper.selectByPrimaryKey((Integer) v.get("uid")).getUsername());
            v.put("time",DateUtils.format((Date)v.get("time"),DateUtils.DATE_TIME_PATTERN));
        });
        pageUtil.setData(mapList);
        return pageUtil;
    }

    @Override
    public List<Activity> getNewArticle() {
        return activityMapper.selectNewActivity();
    }
}
